<?php
namespace app\http;

use think\worker\Server;
use Workerman\Connection\TcpConnection;
use app\admin\model\ServerIpInventory;
use app\admin\model\binance\KeySecret;
use app\admin\model\binance\OrderRecords;

use think\App;
$app = App::getInstance();
$app->initialize();

/**
 * 服务器状态维护服务
 */
class Worker extends Server
{
    protected $socket = 'http://0.0.0.0:2389';
    protected $connections = [];
    protected $serverModel;
    public function __construct()
    {
        parent::__construct();
        $this->serverModel = new ServerIpInventory();
    }
    public function onConnect(TcpConnection  $connection)
    {
        // 新建连接时，将连接保存到连接池中
        $clientIP = $connection->getRemoteIp();
        // 检查IP，不在服务器IP列表中则关闭连接
        $server = $this->serverModel->where(['ip' => $clientIP])->find();
        if(!$server){
            // TODO 记录下非法IP
            $connection->close();
            return;
        }
        $connection->ip = $clientIP;
        $server->online = 1;
        $server->save();
        $this->connections[$connection->id] = $connection;
    }
    public function onClose($connection)
    {
        // 关闭连接时，将连接从连接池中删除
        $server = $this->serverModel->where(['ip' => $this->connections[$connection->id]->ip])->find();
        if($server){
            $server->online = 0;
            $server->save();
        }
        unset($this->connections[$connection->id]);
    }
    public function onMessage(TcpConnection $connection,$data)
    {
        if(empty($data)){
            return ;
        }
        // 解析客户端发送的 JSON 数据
        $msg = json_decode($data, true);
        echo $data . "\n";
        switch ($msg['action']){
            case 'ping': // 更新活跃时间
                ServerIpInventory::update(['last_time' => time()], ['ip' => $this->connections[$connection->id]->ip]);
                $connection->send('{"action":"pong"}');
                break;
            case 'order': // 推送的
                $mappingArray = [
                    's' => 'symbol',
                    'c' => 'clientOrderId',
                    'S' => 'side',
                    'o' => 'type',
                    'ap' => 'avgPrice',
                    "ps"=> "positionSide", /// 持仓方向
                    'z' => 'cumQty',
                    'n' => 'handlingFee',
                    'o' => 'type',
                ];

                $order = array_combine(array_values($mappingArray), array_values($msg['order']));
                $or = OrderRecords::where(['account_id'=>$msg['account_id'],'symbol'=>$order['symbol'],'clientOrderId' => $order['clientOrderId']])->find();
                if($or){
                    $or->save($order);
                }else{
                    OrderRecords::create($order);
                }
                break;
            case 'order_callback': //下单回调
                $order = $msg['data'];
                $order['indexData'] = json_encode($msg['indexData']);

                $or = OrderRecords::where(['account_id'=>$msg['account_id'],'symbol'=>$order['symbol'],'clientOrderId' => $order['clientOrderId']])->find();

                if($or){
                    unset($order['avgPrice']);
                    unset($order['cumQty']);
                    $or->save($order);
                }else{
                    OrderRecords::create($order);
                }
                break;
            case 'accountStarting': // 账户启动中
                KeySecret::update(['online'=>2],['id' => $msg['account_id']]);
                break;
            case 'accountStarted': // 账户启动完成
                KeySecret::update(['online'=>1],['id' => $msg['account_id']]);
                break;
            case 'accountStopped': // 账户启动关闭
                KeySecret::update(['online'=>0],['id' => $msg['account_id']]);
                break;
            case 'accountPing': //账号活跃
                KeySecret::update(['last_time'=>time()],['id' => $msg['account_id']]);
                break;

        }

    }
}